#include "misc.h"

vec2i::vec2i(int nx, int ny) : x(nx), y(ny) {}
vec2i::vec2i(const vec2i& other) : x(other.x), y(other.y) {}
vec2i::vec2i(const vec2f& other) : x(int(other.x)), y(int(other.y)) {}
vec2i& vec2i::operator =(const vec2i& other){ x=other.x; y=other.y; return *this;}
vec2i& vec2i::operator =(const vec2f& other){ x=int(other.x); y=int(other.y); return *this;}
int vec2i::dot(const vec2i& r) const { return x*r.x+y*r.y; }
int vec2i::cross(const vec2i& r) const {return x*r.y -y*r.x; }
float vec2i::magnitude() const { return sqrtf(float(x*x+y*y)); }
vec2f vec2i::normalized() const { return vec2f(*this)/magnitude(); }
vec2i& operator+=(vec2i& l, const vec2i& r){
	l.x+=r.x; l.y+=r.y;
	return l;
}
vec2i& operator-=(vec2i& l, const vec2i& r){
	l.x-=r.x; l.y-=r.y;
	return l;
}
vec2i& operator*=(vec2i& l, const vec2i& r){
	l.x*=r.x; l.y*=r.y;
	return l;
}
vec2i& operator/=(vec2i& l, const vec2i& r){
	l.x/=r.x; l.y/=r.y;
	return l;
}
vec2i& operator*=(vec2i& l, int r){
	l.x*=r;
	l.y*=r;
	return l;
}
vec2i& operator/=(vec2i& l, int r){
	l.x/=r;
	l.y/=r;
	return l;
}
vec2i operator+(const vec2i& l, const vec2i& r){
	return vec2i(l.x+r.x, l.y+r.y);
}
vec2i operator-(const vec2i& l, const vec2i& r){
	return vec2i(l.x-r.x, l.y-r.y);
}
vec2i operator*(const vec2i& l, const vec2i& r){
	return vec2i(l.x*r.x, l.y*r.y);
}
vec2i operator/(const vec2i& l, const vec2i& r){
	return vec2i(l.x/r.x, l.y/r.y);
}
vec2i operator*(const vec2i& l, int r){
	return vec2i(l.x*r, l.y*r);
}
vec2i operator/(const vec2i& l, int r){
	return vec2i(l.x/r, l.y/r);
}
vec2i operator*(int l, const vec2i& r){
	return r*l;
}
vec2i operator-(const vec2i& r){
	return vec2i(-r.x, -r.y);
}



vec2f::vec2f(float nx, float ny) : x(nx), y(ny) {}
vec2f::vec2f(const vec2f& other) : x(other.x), y(other.y) {}
vec2f::vec2f(const vec2i& other) : x(other.x), y(other.y) {}
vec2f& vec2f::operator =(const vec2f& other){ x=other.x; y=other.y; return *this;}
vec2f& vec2f::operator =(const vec2i& other){ x=other.x; y=other.y; return *this;}
float vec2f::dot(const vec2f& r) const { return x*r.x+y*r.y; }
float vec2f::cross(const vec2f& r) const {return x*r.y -y*r.x; }
float vec2f::magnitude() const { return sqrtf(x*x+y*y); }
vec2f vec2f::normalized() const { return (*this)/magnitude(); }
vec2f& operator+=(vec2f& l, const vec2f& r){
	l.x+=r.x; l.y+=r.y;
	return l;
}
vec2f& operator-=(vec2f& l, const vec2f& r){
	l.x-=r.x; l.y-=r.y;
	return l;
}
vec2f& operator*=(vec2f& l, const vec2f& r){
	l.x*=r.x; l.y*=r.y;
	return l;
}
vec2f& operator/=(vec2f& l, const vec2f& r){
	l.x/=r.x; l.y/=r.y;
	return l;
}
vec2f& operator*=(vec2f& l, float r){
	l.x*=r;
	l.y*=r;
	return l;
}
vec2f& operator/=(vec2f& l, float r){
	l.x/=r;
	l.y/=r;
	return l;
}
vec2f operator+(const vec2f& l, const vec2f& r){
	return vec2f(l.x+r.x, l.y+r.y);
}
vec2f operator-(const vec2f& l, const vec2f& r){
	return vec2f(l.x-r.x, l.y-r.y);
}
vec2f operator*(const vec2f& l, const vec2f& r){
	return vec2f(l.x*r.x, l.y*r.y);
}
vec2f operator/(const vec2f& l, const vec2f& r){
	return vec2f(l.x/r.x, l.y/r.y);
}
vec2f operator*(const vec2f& l, float r){
	return vec2f(l.x*r, l.y*r);
}
vec2f operator/(const vec2f& l, float r){
	return vec2f(l.x/r, l.y/r);
}
vec2f operator*(float l, const vec2f& r){
	return r*l;
}
vec2f operator-(const vec2f& r){
	return vec2f(-r.x, -r.y);
}

void pathTrace(const vec2f& path, std::vector<vec2i>& traversedPoints) {
	traversedPoints.clear();
	int x0 = 0, y0 = 0, x1 = (int) path.x, y1 = (int) path.y;
	bool steep = abs(y1 - y0) > abs(x1 - x0);
	if (steep) {
		std::swap(x0, y0);
		std::swap(x1, y1);
	}
	/*if (x0 > x1) {
		std::swap(x0, x1);
		std::swap(y0, y1);
	}*/
	int deltax = abs(x1 - x0);
	int deltay = abs(y1 - y0);
	int error = deltax / 2;
	int ystep;
	int xstep;
	int y = y0;
	if (y0 < y1)
		ystep = 1;
	else
		ystep = -1;
	if (x0 < x1)
		xstep = 1;
	else
		xstep = -1;

	for (int x = x0; x != x1; x+=xstep) {
		if (steep)
			traversedPoints.push_back(vec2i(y, x));
		else
			traversedPoints.push_back(vec2i(x, y));
		error = error - deltay;
		if (error < 0) {
			y += ystep;
			error += deltax;
		}
	}

}
void pointsInCircle(float magnitude, std::vector<vec2i>& occupiedPoints){
	occupiedPoints.clear();
	int iRadius=(int)ceilf(magnitude);
	for(int y=-iRadius; y<=iRadius; ++y){
		for(int x=-iRadius; x<=iRadius; ++x){
			vec2i point(x,y);
			if(point.magnitude()<=magnitude)
				occupiedPoints.push_back(point);
		}
	}
}



